package main

import (
	"fmt"
	"time"
)

// chann的基本用法
func basicChannel() {
	ch := make(chan int)

	go func() {
		fmt.Println("发后前")
		ch <- 42
		fmt.Println("发送后")
	}()
	time.Sleep(1 * time.Second)
	fmt.Println("接收到数据", <-ch)
}

// 缓冲通道
func bufferedChannel() {
	ch := make(chan string, 2)
	ch <- "Hello"
	ch <- "Go"
	fmt.Println(<-ch)
	fmt.Println(<-ch)
}

// 多路复用
// 创建俩个chan 双协程 select 等待
func selectDemo() {
	ch1 := make(chan string)
	ch2 := make(chan string)

	go func() { time.Sleep(100 * time.Millisecond); ch1 <- "通道1" }()
	go func() { time.Sleep(50 * time.Millisecond); ch2 <- "通道2" }()

	select {
	case msg := <-ch1:
		fmt.Println(msg)

	case msg := <-ch2:
		fmt.Println(msg)
	case <-time.After(200 * time.Millisecond):
		fmt.Println("超时了")
	}
}

// 生产者消费者模型
func producerConsumer() {
	jobs := make(chan int, 5)
	done := make(chan bool)

	//消费者
	go func() {
		for jobs := range jobs {
			fmt.Println("执行任务:", jobs)
			time.Sleep(200 * time.Millisecond)
		}
		fmt.Println("任务完成")
		done <- true
	}()

	for i := 0; i < 3; i++ {
		jobs <- i
		fmt.Println("提交任务")
	}
	close(jobs) //会停止range的信道
	<-done
}

func main() {
	// basicChannel()
	// fmt.Println("*****************************************")
	// bufferedChannel()
	// fmt.Println("*****************************************")
	// selectDemo()
	fmt.Println("*****************************************")
	producerConsumer()
}
